<?php
/**
 * 兑换码系统功能测试脚本
 * 测试兑换码的生成、验证、使用等核心功能
 */

// 引入框架
require_once __DIR__ . '/vendor/autoload.php';

// 初始化应用
$app = new think\App();
$app->initialize();

use app\common\model\RedemptionCode;
use app\common\model\RedemptionCodeBatch;
use app\common\model\RedemptionCodeUsage;
use think\facade\Db;

echo "=== 兑换码系统功能测试 ===\n\n";

try {
    // 测试1: 生成兑换码
    echo "1. 测试兑换码生成功能\n";
    
    // 测试单个兑换码生成
    $code1 = RedemptionCode::generateUniqueCode('TEST', 8);
    echo "生成的兑换码: {$code1}\n";
    
    // 验证生成的兑换码格式
    if (strlen($code1) === 8 && strpos($code1, 'TEST') === 0) {
        echo "✓ 兑换码格式正确\n";
    } else {
        echo "✗ 兑换码格式错误\n";
    }
    
    // 测试2: 创建兑换码批次
    echo "\n2. 测试兑换码批次创建\n";
    
    $batchData = [
        'title' => '测试批次_' . date('YmdHis'),
        'description' => '测试用兑换码批次',
        'total_count' => 5,
        'code_length' => 8,
        'code_prefix' => 'TEST',
        'discount_amount' => 10.00,
        'discount_percent' => 0,
        'max_uses_per_code' => 1,
        'start_time' => time(),
        'end_time' => time() + 86400 * 30, // 30天后过期
        'admin_id' => 1,
        'status' => RedemptionCodeBatch::STATUS_ACTIVE,
        'create_time' => time(),
        'update_time' => time(),
    ];
    
    $batch = new RedemptionCodeBatch();
    $batchId = $batch->insertGetId($batchData);
    
    if ($batchId) {
        echo "✓ 批次创建成功，ID: {$batchId}\n";
        
        // 生成兑换码
        $codes = $batch->generateRedemptionCodes($batchId, 5, 'TEST', 8);
        echo "✓ 生成了 " . count($codes) . " 个兑换码\n";
        
        // 显示生成的兑换码
        foreach ($codes as $index => $code) {
            echo "  - 兑换码 " . ($index + 1) . ": {$code}\n";
        }
    } else {
        echo "✗ 批次创建失败\n";
    }
    
    // 测试3: 验证兑换码
    echo "\n3. 测试兑换码验证功能\n";
    
    if (!empty($codes)) {
        $testCode = $codes[0];
        $redemptionCode = RedemptionCode::where('code', $testCode)->find();
        
        if ($redemptionCode) {
            echo "✓ 兑换码查询成功: {$testCode}\n";
            
            // 检查状态
            if ($redemptionCode->status == RedemptionCode::STATUS_ACTIVE) {
                echo "✓ 兑换码状态正确 (ACTIVE)\n";
            } else {
                echo "✗ 兑换码状态错误: {$redemptionCode->status}\n";
            }
            
            // 检查过期时间
            if (!$redemptionCode->isExpired()) {
                echo "✓ 兑换码未过期\n";
            } else {
                echo "✗ 兑换码未在有效期内\n";
            }
            
            // 检查使用次数
            if ($redemptionCode->used_count < $redemptionCode->max_uses_per_code) {
                echo "✓ 兑换码可以使用 (已使用: {$redemptionCode->used_count}/{$redemptionCode->max_uses_per_code})\n";
            } else {
                echo "✗ 兑换码使用次数已达上限\n";
            }
        } else {
            echo "✗ 兑换码查询失败\n";
        }
    }
    
    // 测试4: 模拟使用兑换码
    echo "\n4. 测试兑换码使用功能\n";
    
    if (!empty($codes) && isset($redemptionCode)) {
        $testUserId = 1; // 假设用户ID为1
        $testOrderId = 0; // 不关联订单
        
        Db::startTrans();
        try {
            $result = $redemptionCode->use($testUserId, $testOrderId);
            
            if ($result) {
                echo "✓ 兑换码使用成功\n";
                
                // 检查使用记录
                $usage = RedemptionCodeUsage::where('code_id', $redemptionCode->id)
                    ->where('user_id', $testUserId)
                    ->find();
                    
                if ($usage) {
                    echo "✓ 使用记录创建成功\n";
                } else {
                    echo "✗ 使用记录创建失败\n";
                }
                
                // 检查兑换码状态更新
                $redemptionCode->refresh();
                if ($redemptionCode->used_count == 1) {
                    echo "✓ 兑换码使用次数更新正确\n";
                } else {
                    echo "✗ 兑换码使用次数更新错误\n";
                }
                
                // 对于单次使用的兑换码，应该被禁用
                if ($redemptionCode->max_uses_per_code == 1 && 
                    $redemptionCode->status == RedemptionCode::STATUS_DISABLED) {
                    echo "✓ 单次使用兑换码已正确禁用\n";
                } else if ($redemptionCode->max_uses_per_code > 1) {
                    echo "✓ 多次使用兑换码状态保持活跃\n";
                }
                
            } else {
                echo "✗ 兑换码使用失败\n";
            }
            
            Db::commit();
        } catch (Exception $e) {
            Db::rollback();
            echo "✗ 兑换码使用异常: " . $e->getMessage() . "\n";
        }
    }
    
    // 测试5: 重复使用检查
    echo "\n5. 测试重复使用检查\n";
    
    if (!empty($codes) && isset($redemptionCode)) {
        try {
            $result = $redemptionCode->use($testUserId, $testOrderId);
            
            if (!$result) {
                echo "✓ 重复使用检查正常，阻止了重复使用\n";
            } else {
                echo "✗ 重复使用检查失败，允许了重复使用\n";
            }
        } catch (Exception $e) {
            echo "✓ 重复使用检查正常，抛出异常: " . $e->getMessage() . "\n";
        }
    }
    
    echo "\n=== 测试完成 ===\n";
    
    // 清理测试数据
    echo "\n清理测试数据...\n";
    if (isset($batchId)) {
        // 删除生成的兑换码
        RedemptionCode::where('batch_id', $batchId)->delete();
        // 删除使用记录
        RedemptionCodeUsage::where('code_id', 'in', function($query) use ($batchId) {
            $query->table('ba_redemption_code')->where('batch_id', $batchId)->field('id');
        })->delete();
        // 删除批次
        RedemptionCodeBatch::where('id', $batchId)->delete();
        echo "✓ 测试数据清理完成\n";
    }
    
} catch (Exception $e) {
    echo "测试过程中发生错误: " . $e->getMessage() . "\n";
    echo "错误文件: " . $e->getFile() . "\n";
    echo "错误行号: " . $e->getLine() . "\n";
}